package com.nmf.site.biz.pay.wechat.service;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.SortedMap;
import java.util.TreeMap;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.nmf.site.biz.pay.wechat.EnvVarService;
import com.nmf.site.biz.pay.wechat.conf.HwWechatConfVo;
import com.nmf.site.biz.pay.wechat.entity.TenOpenVo;
import com.nmf.site.biz.pay.wechat.entity.TenPayPreVo;
import com.nmf.site.biz.pay.wechat.entity.TenPayVo;
import com.nmf.site.biz.pay.wechat.util.Sha1Util;
import com.nmf.site.biz.pay.wechat.util.TenMD5Util;
import com.nmf.site.biz.pay.wechat.util.TenpayUtil;
import com.nmf.site.common.excep.KideException;
import com.nmf.site.common.excep.KideExpCode;
import com.nmf.site.common.utils.HttpClientService;

@Component
public class WechatJsWebPay {
	Logger log = LoggerFactory.getLogger(WechatJsWebPay.class);
	@Autowired
	HttpClientService httpClientService;

	@Value("${wechat.pay.notifyurl}")
	public String notify_url;
	@Value("${wechat.pay.webOauthUrl}")
	public String webOauthUrl;//授权后跳转页面
	@Value("${wechat.pay.wchatcode}")
	public String wchatcodeUrl;
	public TenPayPreVo getPayUrl(String code) {
		HwWechatConfVo hwWechatConfVo = new HwWechatConfVo();
		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
		String timestamp = Sha1Util.getTimeStamp();
		String nonceStr2 = TenpayUtil.getRandomString(20);

		TenOpenVo tenOpenVo = getOpenId(code);
//		TenPayPreVo tenPayPreVo = getPrePayId(tenOpenVo, bizOrder.getPrice(), bizOrder.getOrderNo(), bizOrder.getOrderNo(), "127.0.0.1","");
		TenPayPreVo tenPayPreVo = new TenPayPreVo();
		String prepay_id2 = "prepay_id=" + tenPayPreVo.getPayPreId();
		String packages = prepay_id2;


		finalpackage.put("appId", hwWechatConfVo.getAppId());
		finalpackage.put("timeStamp", timestamp);
		finalpackage.put("nonceStr", nonceStr2);
		finalpackage.put("package", packages);
		finalpackage.put("signType", "MD5");
		String finalsign = TenMD5Util.createSign(finalpackage, hwWechatConfVo.getSecurityCode(), hwWechatConfVo.getCharsetStr());
		TenPayVo tenPayVo = new TenPayVo();
		tenPayVo.setAppId(hwWechatConfVo.getAppId());
		tenPayVo.setNonceStr(nonceStr2);
		tenPayVo.setPackageInfo(packages);
		tenPayVo.setSignInfo(finalsign);
		tenPayVo.setTimestamp(timestamp);

		tenPayPreVo.setTenPayVo(tenPayVo);
		return tenPayPreVo;
	}
	public TenPayPreVo getPrePayId(TenOpenVo tenOpenVo, Double amount, String payNo, String orderNo, String ip,String msg) {
		log.info("wechat支付开始 获取prepay_id");
		long time = System.currentTimeMillis();
		String currTime = TenpayUtil.getCurrTime();
		// 8位日期
		String strTime = currTime.substring(8, currTime.length());
		// 四位随机数
		String strRandom = TenpayUtil.buildRandom(4) + "";
		// 10位序列号,可以自行调整。
		String strReq = strTime + strRandom;

		String nonce_str = strReq;
		String body = "凯顿订单支付";
		// 附加数据
		String attach = orderNo;
		// 商户订单号
		String out_trade_no = payNo;
		// 总金额以分为单位，不带小数点
		int total_fee = new Double(amount * 100d).intValue();
		
		if(EnvVarService.isTest()) {
			total_fee = 1;
		}
		// 订单生成的机器 IP
		String spbill_create_ip = ip;
		time = System.currentTimeMillis();
		// 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。

//		String trade_type = "NATIVE";
		String trade_type = "JSAPI";

		HwWechatConfVo hwWechatConfVo = new HwWechatConfVo();
		// String product_id = "";
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", HwWechatConfVo.appId);
		packageParams.put("mch_id", HwWechatConfVo.mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);
		packageParams.put("attach", attach);
		packageParams.put("out_trade_no", out_trade_no);
		log.info("v1.0/p/wchat/pd 2.2:" + (System.currentTimeMillis() - time));
		time = System.currentTimeMillis();
		packageParams.put("total_fee", total_fee + "");
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);

		packageParams.put("trade_type", trade_type);
		packageParams.put("openid", tenOpenVo.getOpendId());
		String sign = TenMD5Util.createSign(packageParams, HwWechatConfVo.securityCode, HwWechatConfVo.charsetStr);
		packageParams.put("sign", sign);
		String xml = TenpayUtil.getRequestXml(packageParams);
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		time = System.currentTimeMillis();
		String prepayIdXML;
		try {
			prepayIdXML = httpClientService.postJSON(createOrderURL, xml);
			log.info("获取purl 为：" + prepayIdXML);
		} catch (IOException e) {
			log.error("获取 prepay_id 错误");
			throw new KideException(KideExpCode.PAY_ERROR,e.toString());
		}
		log.info("v1.0/p/wchat/pd 2.4:" + (System.currentTimeMillis() - time));
		time = System.currentTimeMillis();
		Document document = Jsoup.parse(prepayIdXML, "UTF-8");
		Elements rcodeList = document.getElementsByTag("return_code");

		if (rcodeList.size() > 0) {
			Element ele = rcodeList.get(0);

			String datastr = ele.ownText();

			if (datastr.toLowerCase().equals("success")) {
				Elements elist = document.getElementsByTag("prepay_id");
				Elements codeUelist =document.getElementsByTag("code_url");
				TenPayPreVo tenPayPreVo = new TenPayPreVo();
				tenPayPreVo.setPayPreId(elist.get(0).ownText());
				tenPayPreVo.setAccessToken(tenOpenVo.getAccessToken());
				tenPayPreVo.setOpenId(tenOpenVo.getOpendId());
				if(codeUelist!=null && codeUelist.size()>0) {
					tenPayPreVo.setCode_url(codeUelist.get(0).ownText());
				}
				return tenPayPreVo;
			} else {
				log.error("获取prepay_id错误 ，wechat 返回报文：" + prepayIdXML);
			}
		}
		time = System.currentTimeMillis();
		throw new KideException(KideExpCode.PAY_ERROR,"openId:" + tenOpenVo.getOpendId() + "	amount" + amount + "	payNo" + payNo + "	orderNo" + orderNo + "	ip:" + ip);
	}


	public TenOpenVo getOpenId(String code) {
		HwWechatConfVo hwWechatConfVo = new HwWechatConfVo();
		String grant_type = "authorization_code";
		String reqUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + hwWechatConfVo.getAppId() + "&secret=" + hwWechatConfVo.getAppSecret() + "&code=" + code + "&grant_type=" + grant_type;

		String rspstr;
		try {
			rspstr = httpClientService.sendReq(reqUrl);
		} catch (IOException e) {
			log.error("获取openid 错误");
			throw new KideException(KideExpCode.PAY_ERROR,e.toString());
		}
		log.info("获取 open id 为：" + rspstr);

		TenOpenVo tenOpenVo = new TenOpenVo();
		JSONObject jsonbject = JSON.parseObject(rspstr);
		tenOpenVo.setOpendId(jsonbject.getString("openid"));
		tenOpenVo.setAccessToken(jsonbject.getString("access_token"));
		tenOpenVo.setRefreshToken(jsonbject.getString("refresh_token"));
		tenOpenVo.setScope(jsonbject.getString("scope"));

		return tenOpenVo;
	}

	
	public String createWebOauthUrlForCode(String orderNo) {
		HwWechatConfVo hwWechatConfVo = new HwWechatConfVo();
		String dwebOauthUrl = wchatcodeUrl+"?orderNo="+orderNo;
		String reqUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +hwWechatConfVo.getAppId() + "&redirect_uri=" + URLEncoder.encode(dwebOauthUrl) + "&response_type=code&scope=snsapi_base#wechat_redirect";
		return reqUrl;
	}
	
	public String createWebOauthUrlForMember(String rurl,String equipNo) {
		HwWechatConfVo hwWechatConfVo = new HwWechatConfVo();
		String dwebOauthUrl = rurl+"?equipNo="+equipNo;
		String reqUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" +hwWechatConfVo.getAppId() + "&redirect_uri=" + URLEncoder.encode(dwebOauthUrl) + "&response_type=code&scope=snsapi_base#wechat_redirect";
		return reqUrl;
	}
	
	public TenOpenVo getTenOpenVo(String code) {
		TenOpenVo tenOpenVo = getOpenId(code);
		return tenOpenVo;
	}

	
}
